package my.webservices.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;

import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.oxm.castor.CastorMarshaller;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.SourceExtractor;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.security.xwss.XwsSecuritySecurementException;

import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSecurityException;

/**
 * VehicleHistSearchClient is the client for vehicle history search service.
 * 
 * @author Nilaksh Bajpai.
 */
public class VehicleHistSearchClient {

	private Resource request;

	private static XWSSProcessor cprocessor;

	private static ProcessingContext context;

	/**
	 * Default constructor.
	 */
	public VehicleHistSearchClient() {
		super();
	}

	/**
	 * Spring's web service template.
	 */
	private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

	/**
	 * Setter for default uri injection.
	 * 
	 * @param defaultUri
	 */
	public void setDefaultUri(final String defaultUri) {
		webServiceTemplate.setDefaultUri(defaultUri);
	}

	public void setMarshaller(final CastorMarshaller marshaller) {
		webServiceTemplate.setMarshaller(marshaller);
	}

	/**
	 * Send message to the configured default URI.
	 * 
	 * @param message
	 * @return
	 * @throws IOException 
	 * @throws XWSSecurityException 
	 */
	public boolean simpleSendAndReceive(final String message) throws XWSSecurityException, IOException {

		// xwss
		Resource xwssConfig = new ClassPathResource("wss-client-policy.xml");
		if (!xwssConfig.exists()) {
			throw new FileNotFoundException();
		}

		XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
		cprocessor = factory.createProcessorForSecurityConfiguration(
				xwssConfig.getInputStream(), null);
		context = new ProcessingContext();

		StreamSource source = new StreamSource(new StringReader(message));
		StreamResult result = new StreamResult(System.out);

		SourceExtractor sourceExtractor = new SourceExtractor() {

			public Object extractData(final Source arg0) throws IOException,
					TransformerException {
				// TODO Auto-generated method stub
				return null;
			}
		};
		return webServiceTemplate.sendSourceAndReceiveToResult(source,
				new WebServiceMessageCallback() {
					public void doWithMessage(WebServiceMessage message)
							throws IOException {
						// We can cast safley to SaajSoapMessage
						SaajSoapMessage saajSoapMessage = (SaajSoapMessage) message;
						SOAPMessage saajMessage = saajSoapMessage
								.getSaajMessage();
						try {
							context.setSOAPMessage(saajMessage);
							SOAPMessage securedMessage = cprocessor
									.secureOutboundMessage(context);
							saajSoapMessage.setSaajMessage(securedMessage);

						} catch (XWSSecurityException e) {
							throw new XwsSecuritySecurementException(e
									.getMessage());
						}

					}
				}, result);
		// return webServiceTemplate.marshalSendAndReceive(source);
		// return webServiceTemplate.sendSourceAndReceive(source,
		// sourceExtractor);
	}
}